package com.warren.system.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.Query;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.warren.response.Result;
import com.warren.response.ResultCode;
import com.warren.system.entity.*;
import com.warren.system.mapper.MenuMapper;
import com.warren.system.mapper.RoleMapper;
import com.warren.system.mapper.RoleMenuMapper;
import com.warren.system.mapper.UserRoleMapper;
import com.warren.system.service.RoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.warren.system.vo.RoleVO;
import com.warren.util.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author warren
 * @since 2021-03-21
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Override
    public List<Long> findMenuIdsByRoleId(Long id) {
        Role role = baseMapper.selectById(id);
        if (role == null){
            throw new Error("该角色不存在");
        }
        QueryWrapper<RoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id",id);
        List<Long> ids = new ArrayList<>();
        List<RoleMenu> roleMenus = roleMenuMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(roleMenus)){
            for (RoleMenu roleMenu : roleMenus){
                ids.add(roleMenu.getMenuId());
            }
        }
        return ids;
    }

    @Override
    public void authority(Long id, Long[] mids) {
        //删除之前角色的菜单
        Role role = baseMapper.selectById(id);
        if (role == null){
            throw new Error("角色不存在");
        }
        QueryWrapper<RoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id",id);
        //删除之前分配的
        roleMenuMapper.delete(queryWrapper);
        //增加现在分配
        if (mids.length > 0){
            for (Long mid : mids){
                Menu menu = menuMapper.selectById(mid);
                if (menu == null){
                    throw  new Error("menuId=" + mid + ",该菜单不存在");
                }else{
                    RoleMenu roleMenu = new RoleMenu();
                    roleMenu.setRoleId(id);
                    roleMenu.setMenuId(mid);
                    roleMenuMapper.insert(roleMenu);
                }
            }
        }
        //清除所有菜单redis缓存
        Set<String> keys = redisUtils.keys("menus_" + "*");
        redisUtils.sdel(keys);
    }

    @Override
    public void updateStatus(Role role) {
        baseMapper.updateById(role);
    }

    @Override
    public Result delRole(Long id) {
        QueryWrapper<UserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id",id);
        Integer count = userRoleMapper.selectCount(queryWrapper);
        if (count != 0){
            return Result.error(ResultCode.ROLE_HAVE_USER);
        }
        baseMapper.deleteById(id);
        return Result.ok();
    }

    @Override
    public void exportRoleExcel(HttpServletResponse response, List<Role> roles) throws IOException {
        //写入excel文件
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        String exportFileName = "角色列表.xlsx";
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        response.addHeader("Content-disposition", "attachment;filename=" + exportFileName );
        EasyExcel.write(response.getOutputStream(), Role.class).
                sheet("角色信息")
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .doWrite(roles);
    }
}
